[0.7.1] Release - #36
Closed
AGiorgetti wants to merge 12 commits into
Closed
Conversation
… DependsOn - Added return statements after inner TryAdd* calls when dependsOn.Length == 0 - Prevents unnecessary reflection calls to GetConstructorAndParameters - Avoids potential double-registration attempts - Fixes 14 TryAdd* method overloads: - TryAddSingleton (3 overloads) - TryAddScoped (3 overloads) - TryAddTransient (2 overloads) - TryAddKeyedSingleton (2 overloads) - TryAddKeyedScoped (2 overloads) - TryAddKeyedTransient (2 overloads)
- Changed GetServiceDescriptors to use unidirectional type matching: serviceType == serviceDescriptor.ServiceType || serviceType.IsAssignableFrom(serviceDescriptor.ServiceType) - This prevents unrelated base-type registrations (like object) from incorrectly matching specific type queries, which was causing .Last() to return wrong descriptors - Fixes incorrect lifetime checks in IsTransientServiceRegistered, IsSingletonServiceRegistered, IsScopedServiceRegistered and their keyed variants - Added 6 comprehensive tests to verify the fix and prevent regression
…19 tests Co-authored-by: AGiorgetti <246067+AGiorgetti@users.noreply.github.com>
…able Co-authored-by: AGiorgetti <246067+AGiorgetti@users.noreply.github.com>
Co-authored-by: AGiorgetti <246067+AGiorgetti@users.noreply.github.com>
…g to prevent stack corruption on factory exception Co-authored-by: AGiorgetti <246067+AGiorgetti@users.noreply.github.com>
Co-authored-by: AGiorgetti <246067+AGiorgetti@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…stead of throwing Co-authored-by: AGiorgetti <246067+AGiorgetti@users.noreply.github.com>
… equality Co-authored-by: AGiorgetti <246067+AGiorgetti@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This pull request introduces version 0.7.1, a patch release focused on critical bug fixes in service registration validation and resolution context tracking. The changes address three main issues: (1) incorrect bidirectional type matching in service descriptor lookups that caused false positives with base types, (2) stack corruption in resolution context tracking when exceptions occur during service resolution, and (3) missing early returns in dependency registration methods that caused unnecessary reflection operations.
Changes:
- Fixed
GetServiceDescriptorsto use unidirectionalIsAssignableFromchecking, preventing incorrect lifetime validation when base types (likeobject) are registered with different lifetimes - Enhanced exception safety by wrapping all
ResolutionContext.CurrentStackPush/Pop operations in try/finally blocks across all four registration paths (non-keyed/keyed × factory/type) - Extended transient disposable detection to include
IAsyncDisposablein addition toIDisposable, with a newIsDisposableTypehelper method - Fixed missing
returnstatements inTryAdd*methods whenDependsOnarrays are empty, avoiding unnecessary reflection and potential double-registration - Updated lifetime check methods to return
falsefor unregistered services instead of throwing exceptions - Changed keyed service comparisons from
==toEquals()for proper value-based equality
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
ServiceCollectionExtensions.Registration.cs |
Fixed bidirectional IsAssignableFrom to unidirectional, updated lifetime checks to return false for empty descriptors, changed key comparisons to use Equals |
ServiceCollectionExtensions.KeyedService.cs |
Added missing return statements in all TryAdd* overloads when dependsOn array is empty |
DetectIncorrectUsageOfTransientDisposables.cs |
Wrapped Push/Pop in try/finally for exception safety, added IAsyncDisposable support via IsDisposableType helper |
ServiceCollectionExtensions.Registration.Tests.cs |
New test file with comprehensive coverage for lifetime check methods returning false for unregistered services |
ServiceProviderExtensions.Registration.Tests.cs |
Added 6 tests for Issue #19 validating unidirectional IsAssignableFrom fixes cross-type matching bugs |
ServiceCollectionExtensions.KeyedService.Tests.cs |
Added 4 tests verifying TryAdd* methods correctly register services with empty DependsOn arrays |
DetectIncorrectUsageOfTransientDisposablesTests.cs |
Added 8 tests for async disposable detection, memory leak prevention, and stack cleanup after exceptions |
Changelog.md |
Added version 0.7.1 section documenting all bug fixes with issue references |
AGiorgetti
force-pushed
the
release/0.7.1
branch
from
February 27, 2026 11:01
ee8f659 to
2c4ab6d
Compare
Contributor
Author
|
The release branch was closed manually using git flow. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This pull request introduces a patch release (0.7.1) focused on bug fixes and improvements to service registration and resolution validation in the dependency injection library. The most significant changes address lifetime check methods, resolution context tracking, and registration behaviors for empty dependency arrays. Comprehensive tests have been added to verify these fixes and behaviors.
Bug Fixes and Validation Improvements
IServiceCollectionlifetime check methods (IsTransientServiceRegistered,IsScopedServiceRegistered,IsSingletonServiceRegistered, and their keyed variants) now returnfalseinstead of throwingInvalidOperationExceptionwhen the service is not registered.ResolutionContextwhen a factory delegate throws an exception by wrapping Push/Pop calls intry/finallyfor all registration paths, ensuring stack cleanliness after exceptions. [1] [2]GetServiceDescriptorsmethod to use unidirectionalIsAssignableFromchecks, preventing incorrect lifetime checks and unrelated base-type registrations.Registration Behavior
returnstatements inTryAdd*overloads with emptyDependsOnarrays, preventing unnecessary reflection and potential double-registration.TryAddSingleton,TryAddScoped,TryAddTransient, andTryAddKeyedSingletoncorrectly register services when provided an empty dependency array. [1] [2]Test Coverage
These changes collectively improve reliability, correctness, and developer experience when working with service registrations and resolution in the library.